var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
// 基础类的定义。
var Disaster = /** @class */ (function () {
    // Methods:
    function Disaster(disasterCode, groups) {
        this.disasterCode = disasterCode;
        this.groups = groups;
    } // 子类super就行
    Disaster.prototype.battle = function () {
        // 省略
    };
    Disaster.prototype.getResult = function () {
        // 省略
        return this.groups;
    };
    return Disaster;
}());
// 具体类1
var reverseDisaster = /** @class */ (function (_super) {
    __extends(reverseDisaster, _super);
    // Attributes:
    // Methods:
    function reverseDisaster(disasterCode, groups) {
        return _super.call(this, disasterCode, groups) || this; //把参数给到父类，让他帮忙处理初始化逻辑。
    }
    reverseDisaster.prototype.battle = function () {
        // 省略
        // 子类具体实现,
        this.groups.reverse(); // 简单reverse一下
        return this.groups;
    };
    reverseDisaster.prototype.getResult = function () {
        // 省略
        return this.groups;
    };
    return reverseDisaster;
}(Disaster));
// 简单工厂类
var DisasterFactory = /** @class */ (function () {
    function DisasterFactory() {
    }
    DisasterFactory.createDisaster = function (disasterCode, groups) {
        switch (disasterCode) {
            case 1:
                return new reverseDisaster(disasterCode, groups);
            default:
                return null;
        }
    };
    return DisasterFactory;
}());
var groups = ["Technology", "Promate", "Origanization"];
// 测试
var ds1 = DisasterFactory.createDisaster(1, groups);
console.log(ds1 === null || ds1 === void 0 ? void 0 : ds1.battle()); // ["C", "B", "A"]


// 搜索框功能增强 - 完整版本
// 输入：用户搜索关键词query
// 处理：关键词匹配 + 结果生成
// 输出：可视化搜索结果弹窗
document.addEventListener('DOMContentLoaded', function() {
    const searchInput = document.getElementById('searchInput');
    const searchButton = document.getElementById('searchButton');
    const searchSuggestions = document.getElementById('searchSuggestions');

    // 搜索建议数据
    const suggestions = [
         '网办大厅', '和谐英语','系统','广科'
    ];
    map_table = {
        '学生管理系统': 'https://xg.gdit.edu.cn/',
        '教务系统': 'http://jw.gdit.edu.cn/jwglxt/xtgl/login_slogin.html',
        '图书馆': 'https://library.gdit.edu.cn',
        '迎新系统': 'http://yx.gdit.edu.cn',
        '国赛优秀论文': 'https://dxs.moe.gov.cn/zx/hd/sxjm/sxjmlw/qkt_sxjm_lw_lwzs.shtml',
        'Mworks科学计算&仿真建模平台': 'https://www.tongyuan.cc/product/download'
    }
    // DRY 原则
    const guangkeSystems = {
            title: '广科的系统们',
            items: [
                { name: '学生管理系统', url: map_table['学生管理系统'] },
                { name: '教务系统', url: map_table['教务系统'] },
                { name: '迎新系统', url: map_table['迎新系统'] }
            ]
    }

    // 搜索关键词映射表
    const searchMap = {
        '网办大厅': guangkeSystems,
        '系统': guangkeSystems,
        '广科': guangkeSystems,
        '迎新': guangkeSystems,
        '数学建模': {
            title: '数学建模资源集合',
            items: [
                { name: 'MATLAB数学建模教程', url: 'https://www.bilibili.com/video/BV1s4411x7G4' },
                { name: '数学建模算法大全', url: 'https://zhuanlan.zhihu.com/p/61463756' },
                { name: '国赛优秀论文', url: map_table['国赛优秀论文'] }
            ]
        },
        'python': {
            title: 'Python学习资源',
            items: [
                { name: 'Python官方文档', url: 'https://docs.python.org/zh-cn/3/' },
                { name: '菜鸟教程Python', url: 'https://www.runoob.com/python3/python3-tutorial.html' },
                { name: '廖雪峰Python教程', url: 'https://www.liaoxuefeng.com/wiki/1016959663602400' }
            ]
        },
        '深度学习': {
            title: '深度学习资源',
            items: [
                { name: '吴恩达深度学习', url: 'https://www.coursera.org/learn/neural-networks-deep-learning' },
                { name: 'PyTorch教程', url: 'https://pytorch.apachecn.org' },
                { name: 'TensorFlow教程', url: 'https://tensorflow.google.cn/tutorials' }
            ]
        }
    };

    // 搜索功能 - 返回真实搜索结果
    function performSearch() {
        const query = searchInput.value.trim();
        if (!query) return;

        console.log('搜索关键词:', query);
        
        // 查找匹配的结果
        let results = null;
        for (const [key, value] of Object.entries(searchMap)) {
            if (query.toLowerCase().includes(key.toLowerCase()) || 
                key.toLowerCase().includes(query.toLowerCase())) {
                results = value;
                break;
            }
        }

        // 显示搜索结果
        if (results) {
            displaySearchResults(results.title, results.items);
        } else {
            // 通用搜索结果
            // 输入：用户搜索关键词query
            // 处理：将谷歌搜索改为Bing搜索，公众号搜索改为秘塔AI搜索
            // 输出：更新后的搜索结果链接
                        displaySearchResults(`关于"${query}"的搜索结果`, [
                            { name: `百度一下: ${query}`, url: `https://www.baidu.com/s?wd=${encodeURIComponent(query)}` },
                            { name: `Bing搜索: ${query}`, url: `https://www.bing.com/search?q=${encodeURIComponent(query)}` },
                            { name: `秘塔AI搜索: ${query}`, url: `https://metaso.cn/search/results?q=${encodeURIComponent(query)}` }
                        ]);
        }

        searchInput.value = '';
        searchSuggestions.classList.remove('active');
    }

    // 显示搜索结果弹窗
    function displaySearchResults(title, items) {
        // 移除已存在的结果容器
        const existingContainer = document.getElementById('searchResults');
        if (existingContainer) {
            existingContainer.remove();
        }

        // 创建结果容器
        const resultsContainer = document.createElement('div');
        resultsContainer.id = 'searchResults';
        resultsContainer.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            padding: 30px;
            max-width: 500px;
            width: 90%;
            max-height: 70vh;
            overflow-y: auto;
            z-index: 1000;
            animation: fadeIn 0.3s ease;
        `;

        // 生成结果HTML
        resultsContainer.innerHTML = `
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
                <h2 style="margin: 0; color: #333; font-size: 1.5rem;">${title}</h2>
                <button onclick="this.parentElement.parentElement.remove()" 
                        style="background: #ff4757; color: white; border: none; border-radius: 50%; width: 30px; height: 30px; cursor: pointer; font-size: 18px;">×</button>
            </div>
            <div style="display: flex; flex-direction: column; gap: 10px;">
                ${items.map(item => `
                    <a href="${item.url}" target="_blank" 
                       style="padding: 15px; background: #f8f9fa; border-radius: 8px; text-decoration: none; color: #333; transition: all 0.3s; border-left: 4px solid #667eea;">
                        <strong>${item.name}</strong>
                        <br><small style="color: #666;">${item.url}</small>
                    </a>
                `).join('')}
            </div>
        `;

        // 添加动画样式
        const animationStyle = document.createElement('style');
        animationStyle.textContent = `
            @keyframes fadeIn {
                from { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
                to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
            }
            #searchResults a:hover {
                background: #e9ecef !important;
                transform: translateY(-2px);
                box-shadow: 0 4px 12px rgba(0,0,0,0.1);
            }
        `;
        document.head.appendChild(animationStyle);

        // 添加到页面
        document.body.appendChild(resultsContainer);

        // 点击外部关闭
        setTimeout(() => {
            document.addEventListener('click', function closeResults(e) {
                if (!e.target.closest('#searchResults') && !e.target.closest('.search-container')) {
                    resultsContainer.remove();
                    document.removeEventListener('click', closeResults);
                }
            });
        }, 100);
    }

    // 事件监听器 - 添加空值检查
    if (searchButton) {
        searchButton.addEventListener('click', performSearch);
    }
    if (searchInput) {
        searchInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter') performSearch();
        });
    }

    // 搜索建议功能 - 添加空值检查
    if (searchInput && searchSuggestions) {
        searchInput.addEventListener('input', function() {
            const value = this.value.toLowerCase();
            if (value.length === 0) {
                searchSuggestions.classList.remove('active');
                return;
            }

            const filtered = suggestions.filter(item => 
                item.toLowerCase().includes(value)
            ).slice(0, 5);

            if (filtered.length > 0) {
                searchSuggestions.innerHTML = filtered
                    .map(item => `<div class="suggestion-item">${item}</div>`)
                    .join('');
                searchSuggestions.classList.add('active');
            } else {
                searchSuggestions.classList.remove('active');
            }
        });

        // 点击建议项
        searchSuggestions.addEventListener('click', function(e) {
            if (e.target.classList.contains('suggestion-item')) {
                searchInput.value = e.target.textContent;
                searchSuggestions.classList.remove('active');
                performSearch();
            }
        });
    }

    // 样式注入
    const style = document.createElement('style');
    style.textContent = `
        .suggestion-item {
            padding: 12px 20px;
            cursor: pointer;
            transition: background-color 0.2s;
            border-bottom: 1px solid #eee;
        }
        .suggestion-item:hover {
            background-color: #f5f5f5;
        }
        .suggestion-item:last-child {
            border-bottom: none;
        }
    `;
    document.head.appendChild(style);
});


// 鸟瞰图功能实现 - 超低延迟实时交互版本
/**
 * 输入：页面DOM结构、滚动位置、用户交互事件
 * 输出：实时页面缩略图、视口位置指示、平滑滚动控制
 */

/**
 * @fileoverview 鸟瞰图功能增强 - 支持鼠标控制页面滚动
 * @author 龙炜轩
 * @date 2025-07-22
 * @input 页面DOM元素、鼠标事件
 * @output 实时页面缩略图、鼠标控制的页面滚动
 */

/**
 * 鸟瞰图视图控制器
 * @class BirdEyeView
 * @description 提供实时页面缩略图和交互式页面导航功能
 * @input 页面DOM结构、滚动事件、鼠标拖拽事件
 * @output 可视化页面缩略图、鼠标控制的页面滚动定位
 */
class BirdEyeView {
    constructor() {
        this.canvas = document.getElementById('birdEyeCanvas');
        this.ctx = this.canvas.getContext('2d');
        this.container = document.getElementById('birdEyeContainer');
        this.viewportIndicator = document.getElementById('viewportIndicator');
        this.isDragging = false;
        this.lastX = 0;
        this.lastY = 0;
        this.scale = 0.1;
        this.updateInterval = 16; // 60fps
        this.lastUpdateTime = 0;
        this.debugMode = false; // 添加调试模式开关
        this.isRunning = false; // 添加运行状态标志
        this.animationFrameId = null; // 存储动画帧ID
        
        // 检查URL参数启用调试模式
        const urlParams = new URLSearchParams(window.location.search);
        this.debugMode = urlParams.has('debug');
        
        if (this.debugMode) {
            console.log('🐛 鸟瞰图调试模式已启用');
        }
        
        this.elementColors = {
            'H1': '#ff6b6b',
            'H2': '#4ecdc4',
            'H3': '#45b7d1',
            'P': '#96ceb4',
            'IMG': '#feca57',
            'A': '#ff9ff3',
            'DIV': '#54a0ff',
            'SECTION': '#5f27cd',
            'NAV': '#00d2d3',
            'UL': '#ff9f43',
            'LI': '#10ac84',
            'BUTTON': '#ee5a24',
            'INPUT': '#0abde3',
            'CANVAS': '#f368e0'
        };
        
        this.init();
    }

    /**
     * 初始化鸟瞰图功能 - 包含边界验证
     * @input 页面加载完成事件
     * @output 初始化画布尺寸、事件监听器、定时更新器、边界验证
     */
    init() {
        this.setupCanvas();
        this.setupEventListeners();
        this.startUpdateLoop();
        this.updateViewport();
        
        // 添加鼠标控制功能
        this.setupMouseControl();
        
        // 边界验证测试
        this.validateDimensions();
        
        // 响应式处理：窗口大小改变时重新计算
        window.addEventListener('resize', () => {
            setTimeout(() => {
                this.setupCanvas(); // 重新计算容器尺寸
                this.update(); // 重新绘制内容
                
                if (this.debugMode) {
                    console.log('🔄 窗口大小改变，重新计算容器尺寸');
                }
            }, 100); // 防抖处理
        });
    }

    /**
     * 验证尺寸计算准确性
     * @input 当前DOM状态
     * @output 尺寸验证报告
     */
    validateDimensions() {
        setTimeout(() => {
            const actualHeaderHeight = this.calculateHeaderHeight();
            const containerRect = this.container.getBoundingClientRect();
            const canvasRect = this.canvas.getBoundingClientRect();
            
            console.log(`✅ Debug Validation:`);
            console.log(`   Container: ${containerRect.width}x${containerRect.height}`);
            console.log(`   Canvas: ${canvasRect.width}x${canvasRect.height}`);
            console.log(`   Header Height: ${actualHeaderHeight}px (was 25px)`);
            console.log(`   Available Space: ${containerRect.height - actualHeaderHeight - 4}px`);
            console.log(`   Scale Factor: ${this.scale.toFixed(4)}`);
            
            // 误差检测
            const expectedCanvasHeight = containerRect.height - actualHeaderHeight - 4;
            const actualError = Math.abs(canvasRect.height - expectedCanvasHeight);
            if (actualError > 1) {
                console.warn(`⚠️  Height mismatch detected: ${actualError}px`);
            } else {
                console.log(`✅ Height calculation accurate within ${actualError}px`);
            }
        }, 100);
    }

    /**
     * 计算标题栏实际高度（改进边界处理）
     * @input 鸟瞰图容器DOM
     * @output 标题栏像素高度（含边界容错）
     */
    calculateHeaderHeight() {
        const titleBar = this.container.querySelector('div[style*="background: #667eea"]');
        if (titleBar) {
            // 增加边界容错：确保返回有效高度
            const height = titleBar.offsetHeight;
            return Math.max(height, 28); // 最小28px防止异常值
        }
        // 改进回退计算：动态适应不同字体和边框
        const computedStyle = window.getComputedStyle(this.container.querySelector('div') || this.container);
        const padding = parseInt(computedStyle.paddingTop) + parseInt(computedStyle.paddingBottom);
        const fontSize = parseInt(computedStyle.fontSize) || 14;
        const border = parseInt(computedStyle.borderTopWidth) + parseInt(computedStyle.borderBottomWidth);
        return Math.max(padding + fontSize + border, 28);
    }

    /**
     * 计算动态容器宽度
     * 基于页面可视区域比例和最小可用宽度进行动态计算
     * 
     * @private
     * @returns {number} 动态容器宽度（像素）
     */
    calculateContainerWidth() {
        const windowWidth = window.innerWidth;
        const windowHeight = window.innerHeight;
        
        // 基础比例：根据页面大小自适应调整
        const baseRatio = Math.min(0.15, 200 / windowWidth); // 最大15%或固定200px中的较小值
        const dynamicRatio = Math.max(baseRatio, 0.08); // 最小8%保证可用性
        
        // 计算动态宽度
        const calculatedWidth = Math.floor(windowWidth * dynamicRatio);
        
        // 边界检查：确保在合理范围内
        const minWidth = 150;  // 最小宽度保证基本功能
        const maxWidth = Math.min(300, windowWidth * 0.25); // 最大宽度限制
        
        const finalWidth = Math.max(minWidth, Math.min(calculatedWidth, maxWidth));
        
        if (this.debugMode) {
            console.log('📐 动态宽度计算:', {
                windowWidth, windowHeight,
                baseRatio, dynamicRatio,
                calculatedWidth, finalWidth,
                minWidth, maxWidth
            });
        }
        
        return finalWidth;
    }

    /**
     * 设置画布尺寸 - 精确版本
     * @input 容器DOM元素、实际标题栏高度
     * @output 精确适配的画布尺寸
     */
    setupCanvas() {
        const rect = this.container.getBoundingClientRect();
        const actualHeaderHeight = this.calculateHeaderHeight();
        
        // 动态计算容器宽度
        const dynamicContainerWidth = this.calculateContainerWidth();
        const dynamicContainerHeight = Math.floor(dynamicContainerWidth * 0.75); // 保持4:3比例
        
        // 更新容器尺寸
        this.container.style.width = `${dynamicContainerWidth}px`;
        this.container.style.height = `${dynamicContainerHeight}px`;
        
        // 精确计算：考虑容器边框(2px*2)和内边距
        const containerBorder = 2;
        const containerPadding = 0;
        
        this.canvas.width = rect.width - (containerBorder * 2) - (containerPadding * 2);
        this.canvas.height = rect.height - actualHeaderHeight - (containerBorder * 2) - (containerPadding * 2);
        
        // 动态缩放计算：确保比例准确
        const pageWidth = document.documentElement.scrollWidth;
        const pageHeight = document.documentElement.scrollHeight;
        
        this.scale = Math.min(
            this.canvas.width / pageWidth,
            this.canvas.height / pageHeight
        );
        
        // 调试日志
        console.log(`📏 Debug: Canvas=${this.canvas.width}x${this.canvas.height}, Scale=${this.scale.toFixed(3)}, Header=${actualHeaderHeight}px`);
    }

    /**
     * 设置事件监听器
     * @input 窗口事件、鼠标事件
     * @output 窗口调整、滚动、鼠标交互事件处理
     */
    setupEventListeners() {
        window.addEventListener('resize', () => this.setupCanvas());
        window.addEventListener('scroll', () => this.updateViewport());
        
        // 拖拽控制
        this.viewportIndicator.addEventListener('mousedown', (e) => this.startDrag(e));
        this.viewportIndicator.addEventListener('touchstart', (e) => this.startDrag(e));
        
        document.addEventListener('mousemove', (e) => this.drag(e));
        document.addEventListener('touchmove', (e) => this.drag(e));
        
        document.addEventListener('mouseup', () => this.endDrag());
        document.addEventListener('touchend', () => this.endDrag());
        
        // 防止文本选择
        this.viewportIndicator.addEventListener('selectstart', (e) => e.preventDefault());
    }

    /**
     * 设置鼠标控制功能
     * @input 鸟瞰图点击事件
     * @output 点击跳转到对应页面位置
     */
    setupMouseControl() {
        this.canvas.addEventListener('click', (e) => this.handleCanvasClick(e));
        this.canvas.style.cursor = 'pointer';
    }

    /**
     * 处理画布点击事件，实现点击跳转
     * @input 鼠标点击事件坐标
     * @output 页面滚动到对应位置
     */
    handleCanvasClick(e) {
        if (this.isDragging) return; // 拖拽时不触发点击
        
        const rect = this.canvas.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;
        
        // 计算对应的页面位置
        const scrollX = (x / this.scale) - (window.innerWidth / 2);
        const scrollY = (y / this.scale) - (window.innerHeight / 2);
        
        // 平滑滚动到目标位置
        window.scrollTo({
            left: Math.max(0, scrollX),
            top: Math.max(0, scrollY),
            behavior: 'smooth'
        });
    }

    /**
     * 开始拖拽
     * @input 鼠标按下事件
     * @output 初始化拖拽状态
     */
    startDrag(e) {
        this.isDragging = true;
        // 缓存拖拽开始时的scale值，确保拖拽过程中使用固定的缩放比例
        this.dragScale = this.scale;
        const clientX = e.clientX || e.touches[0].clientX;
        const clientY = e.clientY || e.touches[0].clientY;
        this.lastX = clientX;
        this.lastY = clientY;
        this.viewportIndicator.style.cursor = 'grabbing';
    }

    /**
     * 拖拽过程
     * @input 鼠标移动事件
     * @output 更新视口位置和页面滚动
     */
    drag(e) {
        if (!this.isDragging) return;
        
        e.preventDefault();
        const clientX = e.clientX || e.touches[0].clientX;
        const clientY = e.clientY || e.touches[0].clientY;
        
        // 使用拖拽开始时缓存的scale值，避免动态scale导致的定位偏移
        const deltaX = (clientX - this.lastX) / this.dragScale;
        const deltaY = (clientY - this.lastY) / this.dragScale;
        
        window.scrollBy(deltaX, deltaY);
        
        this.lastX = clientX;
        this.lastY = clientY;
    }

    /**
     * 结束拖拽
     * @input 鼠标释放事件
     * @output 重置拖拽状态
     */
    endDrag() {
        this.isDragging = false;
        this.viewportIndicator.style.cursor = 'move';
    }

    /**
     * 启动更新循环
     * @input 时间戳
     * @output 定期更新的页面缩略图
     */
    startUpdateLoop() {
        // 存储animation frame ID以便后续可以停止更新
        this.animationFrameId = requestAnimationFrame((timestamp) => {
            const update = (timestamp) => {
                if (timestamp - this.lastUpdateTime > this.updateInterval) {
                    this.update();
                    this.lastUpdateTime = timestamp;
                }
                // 只有在isRunning为true时才继续更新
                if (this.isRunning) {
                    this.animationFrameId = requestAnimationFrame(update);
                }
            };
            update(timestamp);
        });
        this.isRunning = true;
        
        if (this.debugMode) {
            console.log('▶️  鸟瞰图更新循环已启动');
        }
    }
    
    /**
     * 停止更新循环
     * @input 无
     * @output 停止的动画循环
     */
    stopUpdateLoop() {
        if (this.animationFrameId) {
            cancelAnimationFrame(this.animationFrameId);
            this.animationFrameId = null;
        }
        this.isRunning = false;
        
        if (this.debugMode) {
            console.log('⏹️  鸟瞰图更新循环已停止');
        }
    }
    
    /**
     * 刷新鸟瞰图
     * @input 无
     * @output 重新初始化的鸟瞰图
     */
    refresh() {
        if (this.debugMode) {
            console.log('🔄  鸟瞰图已刷新');
        }
        this.setupCanvas();
        this.update();
        
        // 如果更新循环已停止，则重新启动
        if (!this.isRunning) {
            this.startUpdateLoop();
        }
    }

    /**
     * 更新鸟瞰图
     * @input 当前页面DOM状态
     * @output 重新绘制的页面缩略图
     */
    update() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        
        // 在拖拽过程中不重新计算scale，避免定位偏移
        if (!this.isDragging) {
            this.setupCanvas(); // 重新计算缩放
        }
        
        // 绘制页面背景
        this.ctx.fillStyle = '#f8f9fa';
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
        
        // 绘制网格背景
        this.drawGrid();
        
        // 绘制页面元素
        this.drawElements();
        
        // 更新视口指示器
        this.updateViewport();
    }

    /**
     * 绘制网格背景
     * @input 画布尺寸
     * @output 网格线背景
     */
    drawGrid() {
        this.ctx.strokeStyle = '#e9ecef';
        this.ctx.lineWidth = 0.5;
        
        const gridSize = 20;
        for (let x = 0; x < this.canvas.width; x += gridSize) {
            this.ctx.beginPath();
            this.ctx.moveTo(x, 0);
            this.ctx.lineTo(x, this.canvas.height);
            this.ctx.stroke();
        }
        
        for (let y = 0; y < this.canvas.height; y += gridSize) {
            this.ctx.beginPath();
            this.ctx.moveTo(0, y);
            this.ctx.lineTo(this.canvas.width, y);
            this.ctx.stroke();
        }
    }

    /**
     * 绘制页面元素
     * @input 页面DOM元素
     * @output 缩略图上的元素表示
     */
    drawElements() {
        // 优化元素选择，仅选择主要内容区域的元素
        const contentElement = document.querySelector('#future-features') || document.body;
        const elements = contentElement.querySelectorAll('h1, h2, h3, p, div, section');
        
        elements.forEach(element => {
            const rect = element.getBoundingClientRect();
            const elementRect = {
                left: rect.left + window.scrollX,
                top: rect.top + window.scrollY,
                width: rect.width,
                height: rect.height
            };
            
            // 检查元素是否在可视范围内
            if (elementRect.width > 0 && elementRect.height > 0) {
                const x = elementRect.left * this.scale;
                const y = elementRect.top * this.scale;
                const width = Math.min(elementRect.width * this.scale, this.canvas.width - x);
                const height = Math.min(elementRect.height * this.scale, this.canvas.height - y);
                
                // 根据元素类型设置颜色
                const color = this.elementColors[element.tagName] || '#6c757d';
                this.ctx.fillStyle = color;
                this.ctx.globalAlpha = 0.7;
                
                // 绘制元素
                this.ctx.fillRect(x, y, width, height);
                
                // 添加标签名
                if (width > 20 && height > 10) {
                    this.ctx.fillStyle = '#fff';
                    this.ctx.font = '6px Arial';
                    this.ctx.fillText(element.tagName, x + 2, y + 6);
                }
                
                this.ctx.globalAlpha = 1;
            }
        });
    }

    /**
     * 更新视口指示器 - 精确位置计算
     * @input 当前滚动位置和窗口尺寸、页面实际尺寸
     * @output 精确对齐的视口位置指示器
     */
    updateViewport() {
        const scrollX = window.scrollX;
        const scrollY = window.scrollY;
        const windowWidth = window.innerWidth;
        const windowHeight = window.innerHeight;
        
        // 获取页面实际尺寸和可滚动范围
        const pageWidth = document.documentElement.scrollWidth;
        const pageHeight = document.documentElement.scrollHeight;
        const maxScrollX = Math.max(0, pageWidth - windowWidth);
        const maxScrollY = Math.max(0, pageHeight - windowHeight);
        
        // 计算视口在鸟瞰图中的实际尺寸
        const viewportWidthInCanvas = Math.min(windowWidth * this.scale, this.canvas.width);
        const viewportHeightInCanvas = Math.min(windowHeight * this.scale, this.canvas.height);
        
        // 精确计算视口在缩略图中的位置（考虑实际可滚动比例映射）
        let x, y;
        
        if (maxScrollX > 0) {
            // 当页面可水平滚动时，使用比例计算
            x = (scrollX / maxScrollX) * (this.canvas.width - viewportWidthInCanvas);
        } else {
            // 当页面不可水平滚动时，直接映射
            x = Math.min(scrollX * this.scale, this.canvas.width - viewportWidthInCanvas);
        }
        
        if (maxScrollY > 0) {
            // 当页面可垂直滚动时，使用比例计算
            y = (scrollY / maxScrollY) * (this.canvas.height - viewportHeightInCanvas);
        } else {
            // 当页面不可垂直滚动时，直接映射
            y = Math.min(scrollY * this.scale, this.canvas.height - viewportHeightInCanvas);
        }
        
        // 确保位置在有效范围内
        x = Math.max(0, Math.min(x, this.canvas.width - viewportWidthInCanvas));
        y = Math.max(0, Math.min(y, this.canvas.height - viewportHeightInCanvas));
        
        // 应用精确位置
        this.viewportIndicator.style.left = `${x}px`;
        this.viewportIndicator.style.top = `${y}px`;
        this.viewportIndicator.style.width = `${viewportWidthInCanvas}px`;
        this.viewportIndicator.style.height = `${viewportHeightInCanvas}px`;
        
        // 增强调试信息
        if (this.debugMode) {
            console.log(`🎯 视口定位调试:`, {
                scrollX, scrollY,
                maxScrollX, maxScrollY,
                pageWidth, pageHeight,
                windowWidth, windowHeight,
                scale: this.scale.toFixed(4),
                canvas: `${this.canvas.width}x${this.canvas.height}`,
                viewport: `${viewportWidthInCanvas.toFixed(1)}x${viewportHeightInCanvas.toFixed(1)}`,
                position: `${x.toFixed(1)}, ${y.toFixed(1)}`
            });
        }
    }
}

// 全局函数定义 - 确保全局可用
// 输入: 无
// 输出: 切换鸟瞰图显示状态
window.toggleBirdEye = function() {
    const container = document.getElementById('birdEyeContainer');
    if (!container) return;
    
    const isHidden = container.style.display === 'none' || 
                    container.style.opacity === '0' ||
                    !container.offsetParent;
    
    if (isHidden) {
        console.log('🐦 鸟瞰图正在打开...');
        container.style.display = 'block';
        container.style.opacity = '1';
        container.style.visibility = 'visible';
        
        // 确保BirdEyeView已初始化
        if (window.birdEyeView) {
            window.birdEyeView.refresh();
        } else if (window.BirdEyeView) {
            window.birdEyeView = new BirdEyeView();
        }
        
        console.log('✅ 鸟瞰图已成功打开');
    } else {
        console.log('🐦 鸟瞰图正在关闭...');
        container.style.opacity = '0';
        
        // 停止更新循环，真正关闭鸟瞰图
        if (window.birdEyeView) {
            window.birdEyeView.stopUpdateLoop();
        }
        
        setTimeout(() => {
            container.style.display = 'none';
            container.style.visibility = 'hidden';
            console.log('✅ 鸟瞰图已成功关闭');
        }, 300);
    }
};

// 超低延迟初始化
// 输入: 无
// 输出: BirdEyeView实例
window.birdEyeView = null;

// 确保DOM加载完成后立即初始化
// 输入: 无
// 输出: 初始化鸟瞰图
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
        queueMicrotask(() => {
            if (!window.birdEyeView) {
                window.birdEyeView = new BirdEyeView();
                console.log('🐦 鸟瞰图已初始化');
            }
        });
    });
} else {
    // DOM已加载
    queueMicrotask(() => {
        if (!window.birdEyeView) {
            window.birdEyeView = new BirdEyeView();
            console.log('🐦 鸟瞰图已初始化');
        }
    });
}

// 优化键盘快捷键
// 输入: 键盘事件
// 输出: 切换鸟瞰图显示
document.addEventListener('keydown', (e) => {
    if (e.ctrlKey && e.key === 'b') {
        e.preventDefault();
        if (window.toggleBirdEye) {
            window.toggleBirdEye();
        }
    }
});

// 搜索功能模块 - 保留现有实现